package cn.springBoot;

import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Map;

import org.apache.commons.collections.map.CaseInsensitiveMap;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;

import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.BasicAWSCredentials;

public class PostObjectService {

    private AWSCredentials credentials;
    private String endPoint;

    public PostObjectService(String accessKey, String secretKey, String endPoint) {
        if (StringUtils.isEmpty(accessKey) || StringUtils.isEmpty(secretKey) || StringUtils.isEmpty(endPoint)) {
            throw new IllegalArgumentException("create PostObjectClient throw a IllegalArgumentException.");
        }

        this.credentials = new BasicAWSCredentials(accessKey, secretKey);
        this.endPoint = endPoint;
    }

    public HttpResponse postObject(String bucketName, File file, Map<String, String> fileds) throws IOException {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPost request = new HttpPost("http://" + bucketName + "." + endPoint);

        Map<String, String> formFileds = addSigunature(fileds);
        request.setEntity(getEntity(formFileds, file));

        HttpResponse response = httpClient.execute(request);

        return response;
    }

    private Map<String, String> addSigunature(Map<String, String> fileds) {
        Map<String, String> formFileds = new CaseInsensitiveMap();
        formFileds.putAll(fileds);

        if (formFileds.containsKey(PostObjectConstants.POLICY)
            && !formFileds.containsKey(PostObjectConstants.X_AMZ_SIGNATURE)) {
            String signature = new PostObjectSigner().sign(this.credentials, formFileds);
            formFileds.put(PostObjectConstants.X_AMZ_SIGNATURE, signature);
        }

        return formFileds;
    }

    private HttpEntity getEntity(Map<String, String> formFileds, File file) {
        String fileContent = "";
        if (formFileds.containsKey(PostObjectConstants.FILE)) {
            if (file != null) {
                throw new IllegalArgumentException(
                    "POST requires exactly one file upload per request. you shoud choose a way from formFileds text or upload from loacal.");
            } else {
                fileContent = formFileds.get(PostObjectConstants.FILE);
                formFileds.remove(PostObjectConstants.FILE);
            }
        }

        MultipartEntityBuilder multipartEntityBuilder =
            MultipartEntityBuilder.create().setMode(HttpMultipartMode.BROWSER_COMPATIBLE)
                .setBoundary("----------This_Is_The_Default_Boundary").setCharset(Charset.defaultCharset());

        for (Map.Entry<String, String> parameter : formFileds.entrySet()) {
            multipartEntityBuilder.addPart(parameter.getKey(),
                new StringBody(parameter.getValue(), ContentType.create("text/plain", Charset.forName("UTF-8"))));
        }

        if (file != null) {
            // 添加文件
            multipartEntityBuilder.addPart(PostObjectConstants.FILE, new FileBody(file));
        } else {
            multipartEntityBuilder.addPart(PostObjectConstants.FILE,
                new StringBody(fileContent, ContentType.create("text/plain", Charset.forName("UTF-8"))));
        }

        return multipartEntityBuilder.build();
    }

    public void setEndPoint(String endPoint) {
        this.endPoint = endPoint;
    }

    public String getEndPoint() {
        return endPoint;
    }
}
